// /////////////////////////////////////////////////////////////////////////////
//
// Name:            GameManager.h
// Author:          Michael Bartsch (ZCCdark203)
//
// Desc :           Declaration of the GameManager class.
//
// License:         Copyright (C) 2009 Michael Bartsch and Contributors
//
//                  This program is free software: you can redistribute it
//                  and/or modify it under the terms of the zlib/libpng License.
//                  See main.cpp for conditions of distribution and use.
//
// /////////////////////////////////////////////////////////////////////////////

#ifndef __GAMEMANAGER_H__
#define __GAMEMANAGER_H__

// Include files
#include "../dependencies.h"
#include "ReferenceCounted.h"

#include "AssetManager.h"
#include "DataStore.h"
#include "EntityManager.h"
#include "EventManager.h"

#ifdef __COMPILE_WITH_SFML_AUDIO__
   #include "../sound/SoundManager.h"
#endif // __COMPILE_WITH_SFML_AUDIO__

#ifdef __COMPILE_WITH_ANGELSCRIPT__
   #include "../scripting/ScriptManager.h"
#endif // __COMPILE_WITH_ANGELSCRIPT__

#include "../components/components.h"

#include "GameState.h"

// Forward declarations
class GameState;
class ScriptManager;


// GameManager class
//! The Game Manager is the central access point to the game.
//! It is able to perform generic game initialisation and deinitialisation. It's main purpose,
//! though, is to control the flow of the game.
class GameManager : public ReferenceCounted
{
public:

    // Initialisation, deinitialisation and control...
    //! Constructor
    GameManager();
    //! Deconstructor
    ~GameManager();

    //! Returns a pointer to the singleton of the GameManager class.
    static GameManager* Instance();
    //! Returns a reference to the singleton of the GameManager class.
    static GameManager& Reference();

    //! Initialises the GameManager.
    void init();
    //! Updates the GameManager.
    void update();
    //! Clears the GameManager.
    void clear();

    // Reference counting
    //! Increases the reference counter.
    //! @note This is a dummy function.
    void grab();
    //! Decreases the reference counter.
    //! @note This is a dummy function.
    void drop();

    // Public methods
    //! Close the current state and change to the given state.
    //! @param state         Pointer to the new state.
    void changeState(GameState *state);
    //! Pause the current state and change to the given state.
    //! @param state         Pointer to the new state.
    void pushState(GameState *state);
    //! Close the current state and resume the previous state.
    void popState();

    //! Returns a pointer to the Irrlicht Device.
    //! @note Not available in AngelScript.
    IrrlichtDevice* getDevice();
    //! Returns a pointer to the Irrlicht driver.
    //! @note Not available in AngelScript.
	IVideoDriver* getDriver();
	//! Returns a pointer to the Irrlicht SceneManager.
	//! @note Not available in AngelScript.
	ISceneManager* getSceneManager();
	//! Returns a pointer to the Irrlicht GUI Manager.
	//! @note Not available in AngelScript.
	IGUIEnvironment* getGUIEnvironment();

    //! Returns a pointer to the AssetManager.
    AssetManager* getAssetManager();
    //! Returns a pointer to the DataStore.
    DataStore* getDataStore();
    //! Returns a pointer to the EntityManager.
    EntityManager* getEntityManager();
    //! Returns a pointer to the EventManager.
    EventManager* getEventManager();

#ifdef __COMPILE_WITH_ANGELSCRIPT__
	//! Returns a pointer to the ScriptManager.
	ScriptManager* getScriptManager();
#endif // __COMPILE_WITH_ANGELSCRIPT__

#ifdef __COMPILE_WITH_SFML_AUDIO__
	//! Returns a pointer to the Sound Manager.
	SoundManager* getSoundManager();
#endif // __COMPILE_WITH_SFML_AUDIO__

    //! Returns whether the Irrlicht device is running.
	bool getIsRunning() const;

    //! Sets the running state of the Irrlicht device.
	void setIsRunning(bool value);


private:

    // GameManager singleton
    static GameManager *pInstance;

    // Normal members
    vector<GameState*> mGameStates;

    IrrlichtDevice *pDevice;
	IVideoDriver *pDriver;
	ISceneManager *pSceneManager;
    IGUIEnvironment *pGUIEnvironment;

    AssetManager *pAssetManager;
    DataStore *pDataStore;
    EntityManager *pEntityManager;
    EventManager *pEventManager;

#ifdef __COMPILE_WITH_ANGELSCRIPT__
    ScriptManager *pScriptManager;
#endif // __COMPILE_WITH_ANGELSCRIPT__

#ifdef __COMPILE_WITH_SFML_AUDIO__
    SoundManager *pSoundManager;
#endif // __COMPILE_WITH_SFML_AUDIO__

    u32 mLastTime;
};

#endif
